<?php

  /**
   * Arraylist class based on a simple array and implement all array methods.<br />
   *
   * Set an array to become the arraylist to work with.<br />
   * @param array $array The array to work with.
   *
   * @author Dany Mottier
   * @version 2.5.7
   *
   * @link http://be2.php.net/manual/en/function.empty.php
   * @link http://be.php.net/manual/fr/function.array.php
   */
  class ArrayList extends Base implements IArrayList {

    /** @var array The array to work with. */
    private $array = array();

    /**
     * Set an array to become the arraylist to work with.<br />
     *
     * @param array $array The array to work with.
     *
     * @link http://be2.php.net/manual/en/function.empty.php
     */
    public function __construct($array = NULL) {
      if (!empty($array) && is_array($array)) {
        $this->array = $array;
      }
    }

    /**
     * Return the current element in an array.<br />
     * Returns the value of the array element that's currently being pointed to
     * by the internal pointer. It does not move the pointer in any way.<br />
     *
     * @return mixed If the internal pointer points beyond the end of the
     * elements list or the array is empty, returns FALSE.<br /><br />
     *
     * @link http://be2.php.net/manual/en/function.current.php
     */
    public function getCurrent() {
      return current($this->array);
    }

    /**
     * Fetch a key from an array.<br />
     *
     * @return integer Returns the index.<br /><br />
     *
     * @link http://be2.php.net/manual/en/function.key.php
     */
    public function getCurrentKey() {
      return key($this->array);
    }

    /**
     * Return the current key and value pair from an array and advance the
     * array cursor.<br />
     *
     * @return array Returns the current key and value pair from the array array.
     * This pair is returned in a four-element array, with the keys 0, 1, key,
     * and value. Elements 0 and key contain the key name of the array element,
     * and 1 and value  contain the data. If the internal pointer for the array
     * points past the end of the array contents, each() returns FALSE.
     *
     * @link http://be2.php.net/manual/en/function.empty.php
     * @link http://be.php.net/manual/en/function.each.php
     */
    public function getEach() {
      return each($this->array);
    }

    /**
     * Return all the keys of an array.<br />
     *
     * @param string $search If specified, then only keys containing these
     * values are returned.
     *
     * @param boolean $strict As of PHP 5, this parameter determines if strict
     * comparison (===) should be used during the search.
     *
     * @return array Returns an array of all the keys in input.<br /><br />
     *
     * @link http://be2.php.net/manual/en/function.empty.php
     * @link http://be2.php.net/manual/en/function.array-keys.php
     */
    public function getKeys($search = "", $strict = FALSE) {
      if (is_string($search)) {
        if (is_bool($strict)) {
          if (!empty($search)) {
            return array_keys($this->array, $search, $strict);
          } else {
            return array_keys($this->array);
          }
        } else {
          throw new IllegalArgumentException("\$strict parameter must be a boolean.");
        }
      } else {
        throw new IllegalArgumentException("\$search parameter must be a string.");
      }
    }

    /**
     * Return all the values of an array.<br />
     *
     * @return array Returns an indexed array of values.<br /><br />
     *
     * @link http://be2.php.net/manual/en/function.array-values.php
     */
    public function getValues() {
      return array_values($this->array);
    }

    /**
     * Return the item at the matching key.
     * @param mixed $key The key index to get.
     * @return mixed The mixed object at the index key.
     */
    public function getAtIndex($key) {
      return $this->array[$key];
    }

    /**
     * Count elements in the array.<br />
     *
     * @return integer Returns the number of elements.<br /><br />
     *
     * @link http://be2.php.net/manual/en/function.count.php
     */
    public function getLength() {
      return count($this->array);
    }

    /**
     * Checks if the given key or index exists in the array.<br />
     *
     * @param string $key Value to check.
     *
     * @return boolean TRUE on success or FALSE on failure.<br /><br />
     *
     * @link http://be2.php.net/manual/en/function.array-key-exists.php
     */
    public function keyExists($key) {
      if (is_string($key)) {
        return array_key_exists($key, $this->array);
      } else {
        throw new IllegalArgumentException("\$key parameter must be a string.");
      }
    }

    /**
     * Checks if a value exists in an array.<br />
     *
     * @param mixed $value If value is a string, the comparison is done in a
     * case-sensitive manner.
     *
     * @param boolean $strict If the parameter strict is set to TRUE then the
     * function will also check the types of the needle in the haystack .
     *
     * @return boolean TRUE if needle is found in the array, FALSE otherwise.<br /><br />
     *
     * @link http://be2.php.net/manual/en/function.in-array.php
     */
    public function valueExists($value, $strict = FALSE) {
      if (is_string($value)) {
        if (is_bool($strict)) {
          return in_array($value, $this->array, $strict);
        } else {
          throw new IllegalArgumentException("\$strict parameter must be a boolean.");
        }
      } else {
        throw new IllegalArgumentException("\$value parameter must be a string.");
      }
    }

    /**
     * Add a value or a pair key value to the array.<br />
     *
     * @param mixed $value The value to add.
     * @param string $key If specified, the key to index the value.
     *
     * @link http://be.php.net/manual/en/function.empty.php
     */
    public function add($value, $key = "") {
      if (is_string($key) && !empty($key))
        $this->array[$key] = $value;
      else
        $this->array[] = $value;
    }

    /**
     * Changes all keys in an array.<br />
     *
     * @param constant $case Either CASE_UPPER or CASE_LOWER (default).
     *
     * @return array Returns an array with its keys lower or uppercased.<br /><br />
     *
     * @link http://be.php.net/manual/en/function.array-change-key-case.php
     * @see IArrayList
     */
    public function changeKeyCase($case = CASE_LOWER) {
      if ($case == IArrayList::KeyCaseLower || $case == IArrayList::KeyCaseUpper) {
        $this->array = array_change_key_case($this->array, $case);
      } else {
        throw new IllegalArgumentException("\$case parameter must refer to implemented interface.");
      }
    }

    /**
     * Split an array into chunks.<br />
     *
     * @param integer $size The size of each chunk.
     * @param boolean $preserve_keys When set to TRUE keys will be preserved.
     * Default is FALSE which will reindex the chunk numerically.
     *
     * @return array Returns a multidimensional numerically indexed array,
     * starting with zero, with each dimension containing $size elements.<br /><br />
     *
     * @link http://be.php.net/manual/en/function.array-chunk.php
     */
    public function chunk($size, $preserve_keys = FALSE) {
      if (is_int($size)) {
        if (is_bool($preserve_keys)) {
          return array_chunk($this->array, $size, $preserve_keys);
        } else {
          throw new IllegalArgumentException("\$preserve_keys parameter must be a boolean.");
        }
      } else {
        throw new IllegalArgumentException("\$size parameter must be an integer.");
      }
    }

    /**
     * Creates an array by using one array for keys and another for its values.<br />
     *
     * @param array $keys Array of keys to be used. Illegal values for key will
     * be converted to string.
     * @param array $values Array of values to be used.
     *
     * @return array Returns the combined array, FALSE if the number of elements
     * for each array isn't equal or if the arrays are empty.<br /><br />
     *
     * @link http://be.php.net/manual/en/function.array-combine.php
     */
    public function combine($keys, $values) {
      if (is_array($keys)) {
        if (is_array($values)) {
          if (count($keys) == count($values)) {
            return array_combine($keys, $values);
          } else {
            throw new IllegalStateException("Both parameters \$keys and \$values should have an equal number of elements.");
          }
        } else {
          throw new IllegalArgumentException("\$values parameter must be an array.");
        }
      } else {
        throw new IllegalArgumentException("\$keys parameter must be an array.");
      }
    }

    /**
     * Computes the difference of arrays with additional index check.<br />
     * Unlike array_diff() the array keys are used in the comparision.<br />
     *
     * @param array $array An array to compare against.
     *
     * @return array Returns an array containing all the values from the main
     * array that are not present in the other array.<br /><br />
     *
     * @link http://be2.php.net/manual/en/function.array-diff-assoc.php
     */
    public function differentiateAssociative($array) {
      if (is_array($array)) {
        return array_diff_assoc($this->array, $array);
      } else {
        throw new IllegalArgumentException("\$array parameter must be an array.");
      }
    }

    /**
     * Computes the difference of arrays by using a callback function for data
     * comparison.<br />
     *
     * @param array $array The array to compare to.
     * @param string $callback The callback comparison function.
     *
     * @return array Returns an array containing all the values of the main
     * array that are not present in the other array.<br /><br />
     *
     * @link http://be2.php.net/manual/en/function.array-udiff.php
     */
    public function differentiateWithCallBack($array, $callback) {
      if (is_array($array)) {
        if (is_array($callback)) {
          if (count($callback) == 2) {
            return array_udiff($this->array, $array, $callback);
          } else {
            throw new IllegalStateException("The array \$callback must contains the class name and function name, and so must have a length of 2");
          }
        } else {
          throw new IllegalArgumentException("\$callback parameter must be an array.");
        }
      } else {
        throw new IllegalArgumentException("\$array parameter must be an array.");
      }
    }

    //Not yet implemented
    //array_udiff_assoc
    //array_udiff_uassoc

    /**
     * Computes the difference of arrays with additional index check which is
     * performed by a user supplied callback function.<br />
     * <b>DO NOT USE THIS METHOD AS IT IS NOT YET STABLE<b>.<br /><br />
     *
     * @param array $array An array to compare against.
     * @param string $callback The callback function must return an integer less
     * than, equal to, or greater than zero if the first argument is considered
     * to be respectively less than, equal to, or greater than the second.
     *
     * @return array Returns an array containing all the entries from the main
     * array that are not present in any of the other array.<br /><br />
     *
     * @link http://be2.php.net/manual/en/function.array-diff-uassoc.php
     */
    public function differentiateAssociativeWithCallback($array, $callback) {
      if (Validator::Validate($array, Validator::VECTOR) &&
              Validator::Validate($callback, Validator::STRING))
        return array_diff_uassoc($array, $callback);
    }

    /**
     * Computes the difference of arrays using a callback function on the keys
     * for comparison.<br />
     * <b>DO NOT USE THIS METHOD AS IT IS NOT YET STABLE<b>.<br /><br />
     *
     * @param array $array An array to compare against.
     * @param string $callback The callback function must return an integer less
     * than, equal to, or greater than zero if the first argument is considered
     * to be respectively less than, equal to, or greater than the second.
     *
     * @return array Returns an array containing all the entries from the main
     * array that are not present in any of the other array.<br /><br />
     *
     * @link http://be2.php.net/manual/en/function.array-diff-ukey.php
     */
    public function differentiateKeyWithCallBack($array, $callback) {
      if (Validator::Validate($array, Validator::VECTOR) &&
              Validator::Validate($callback, Validator::STRING))
        return array_diff_ukey($array, $callback);
    }

    /**
     * Computes the difference of arrays.<br />
     *
     * @param array $array The array to compare against.
     *
     * @return array Returns an array containing all the entries from the main
     * array that are not present in any of the other array.<br /><br />
     *
     * @link http://be2.php.net/manual/en/function.array-diff.php
     */
    public function differentiate($array) {
      if (is_array($array)) {
        return array_diff($array, $this->array);
      } else {
        throw new IllegalArgumentException("\$array parameter must be an array.");
      }
    }

    /**
     * Fill an array with values.<br />
     *
     * @param integer $start_index The first index of the set array.
     * @param integer $size Number of elements to insert.
     * @param mixed $value Value to use for filling.
     *
     * @link http://be.php.net/manual/en/function.array-fill.php
     */
    public function fill($start_index, $size, $value) {
      if (is_int($start_index)) {
        if (is_int($size)) {
          $this->array = array_fill($start_index, $size, $value);
        } else {
          throw new IllegalArgumentException("\$size parameter must be an integer.");
        }
      } else {
        throw new IllegalArgumentException("\$start_index parameter must be an integer.");
      }
    }

    /**
     * Filters elements of an array using a callback function.<br />
     *
     * @param string $callback The callback function to use. If no callback is
     * supplied, all entries of input equal to FALSE will be removed.
     *
     * @link http://be.php.net/manual/en/language.pseudo-types.php#language.types.callback
     * @link http://be.php.net/manual/en/language.types.boolean.php#language.types.boolean.casting
     * @link http://be.php.net/manual/en/function.array-filter.php
     */
    public function filter($callback) {
      if (is_string($callback) || is_array($callback)) {
        $this->array = array_filter($this->array, $callback);
      } else {
        throw new IllegalArgumentException("\$callback parameter must be a string or an array.");
      }
    }

    /**
     * Exchanges all keys with their associated values in an array.<br />
     *
     * @return boolean Returns the flipped array on success or FALSE on failure.<br /><br />
     *
     * @link http://be.php.net/manual/en/function.array-flip.php
     */
    public function flip() {
      $result = array_flip($this->array);

      if ($result !== FALSE) {
        $this->array = $result;

        return TRUE;
      }
    }

    /**
     * Applies the callback to the elements of the given arrays.<br />
     *
     * @param string $callback Callback function to run for each element in
     * each array.
     *
     * @return array An array containing all the elements of the array after applying
     * the callback function to each one.<br /><br />
     *
     * @link http://be.php.net/manual/en/language.pseudo-types.php#language.types.callback
     * @link http://be.php.net/manual/en/function.array-map.php
     */
    public function map($callback) {
      if (is_string($callback) || is_array($callback)) {
        return array_map($callback, $this->array);
      } else {
        throw new IllegalArgumentException("\$callback parameter must a string or an array.");
      }
    }

    /**
     * Merge two arrays recursively.<br />
     * Merges the elements of one or more arrays together so that the values of
     * one are appended to the end of the previous one. <br />If the input arrays have
     * the same string keys, then the values for these keys are merged together
     * into an array, and this is done recursively, so that if one of the values
     * is an array itself, the function will merge it with a corresponding entry
     * in another array too. <br />If, however, the arrays have the same numeric key,
     * the later value will not overwrite the original value, but will be
     * appended.<br />
     *
     * @param array $array Variable list of arrays to recursively merge.
     *
     * @link Merge
     * @link http://be.php.net/manual/en/function.array-merge-recursive.php
     */
    public function mergeRecursive($array) {
      if (is_array($array)) {
        $this->array = array_merge_recursive($this->array, $array);
      } else {
        throw new IllegalArgumentException("\$array parameter must be an array.");
      }
    }

    /**
     * Merge two arrays.<br />
     *
     * @param array $array Variable list of arrays to recursively merge.
     *
     * @see mergeRecursive
     * @link http://be.php.net/manual/en/function.array-merge.php
     */
    public function merge($array) {
      if (is_array($array)) {
        $this->array = array_merge($this->array, $array);
      } else {
        throw new IllegalArgumentException("\$array parameter must be an array.");
      }
    }

    /**
     * Sort multiple or multi-dimensional arrays.<br />
     * <b>DO NOT USE THIS METHOD AS IT IS NOT YET STABLE<b>.<br /><br />
     *
     * @param mixed $option Sort options for the main array.<br />
     * The options could be SORT_ASC, SORT_DESC, SORT_REGULAR, SORT_NUMERIC or SORT_STRING.
     *
     * @return boolean TRUE on success or FALSE on failure.<br /><br />
     *
     * @link http://be2.php.net/manual/en/function.array-multisort.php
     */
    public function multiSort($option = self::SortAscending) {
      return array_multisort($this->array, $option);
    }

    /**
     * Pad array to the specified length with $value.<br />
     *
     * @param integer $size New size of the array.
     * @param mixed $value Value to pad if the array is less than pad_size.
     *
     * @link http://be.php.net/manual/en/function.array-pad.php
     */
    public function pad($size, $value) {
      if (is_int($size)) {
        $this->array = array_pad($this->array, $size, $value);
      } else {
        throw new IllegalArgumentException("\$size parameter must be an integer.");
      }
    }

    /**
     * Pop the element off the end of array.<br />
     *
     * @return mixed If array is empty, NULL will be
     * returned, else, returns the poped value. Note that the array pointer will
     * be reseted after use.<br /><br />
     *
     * @link http://be.php.net/manual/en/function.array-pop.php
     */
    public function pop() {
      return array_pop($this->array);
    }

    /**
     * Push one or more elements onto the end of array.<br />
     *
     * @param mixed $value The pushed value.
     *
     * @return integer The new number of elements in the array.<br /><br />
     *
     * @link http://be.php.net/manual/en/function.array-push.php
     */
    public function push($value) {
      return array_push($this->array, $value);
    }

    /**
     * Pick one or more random entries out of an array.<br />
     *
     * @param integer $numbers Specifies how many entries you want to pick, if
     * not specified, defaults to 1.
     *
     * @return mixed If you are picking only one entry, the function returns the
     * key for a random entry. Otherwise, it returns an array of keys for the
     * random entries. This is done so that you can pick random keys as well as
     * values out of the array.<br /><br />
     *
     * @link http://be.php.net/manual/en/function.array-rand.php
     */
    public function random($numbers = 1) {
      if (is_int($numbers)) {
        return array_rand($this->array, $numbers);
      } else {
        throw new IllegalArgumentException("\$numbers parameter must be an integer.");
      }
    }

    /**
     * Return an array with elements in reverse order.<br />
     *
     * @param boolean $preserve_keys If set to TRUE keys are preserved.<br /><br />
     *
     * @link http://be.php.net/manual/en/function.array-reverse.php
     */
    public function reverse($preserve_keys = FALSE) {
      if (is_bool($preserve_keys)) {
        $this->array = array_reverse($this->array, $preserve_keys);
      } else {
        throw new IllegalArgumentException("\$preserve_keys parameter must be a boolean.");
      }
    }

    /**
     * Searches the array for a given value and returns the corresponding key if
     * successful.<br />
     *
     * @param mixed $needle The searched value. Note: If needle is a string,
     * the comparison is done in a case-sensitive manner.
     * @param boolean $strict If the third parameter strict is set to TRUE, then
     * the function will also check the types of the needle in the haystack .
     *
     * @return mixed The key for needle. If it is found in the array, FALSE
     * otherwise. If needle is found in haystack more than once, the first
     * matching key is returned. To return the keys for all matching values, use
     * GetKeys() with the search_value parameter instead.<br /><br />
     *
     * @link GetKeys
     * @link http://be.php.net/manual/en/function.array-search.php
     */
    public function search($needle, $strict = FALSE) {
      if (is_bool($strict)) {
        return array_search($needle, $this->array, $strict);
      } else {
        throw new IllegalArgumentException("\$strict parameter must be a boolean.");
      }
    }

    /**
     * Shift an element off the beginning of array.<br />
     *
     * @return mixed The shifted value, or NULL if array is empty.<br /><br />
     *
     * @link http://be.php.net/manual/en/function.array-shift.php
     */
    public function shift() {
      return array_shift($this->array);
    }

    /**
     * Extract a slice of the array.<br />
     *
     * @param integer $offset If offset  is non-negative, the sequence will
     * start at that offset in the array . If offset  is negative, the sequence
     * will start that far from the end of the array .
     *
     * @param integer $length If length is given and is positive, then the
     * sequence will have that many elements in it. If length is given and is
     * negative then the sequence will stop that many elements from the end of
     * the array. If it is omitted, then the sequence will have everything from
     * offset  up until the end of the array.
     *
     * @param boolean $preserve_keys Note that Slice() will reorder and reset
     * the array indices by default. You can change this behaviour by setting
     * preserve_keys to TRUE.
     *
     * @return array Returns the slice.<br /><br />
     *
     * @link http://fr2.php.net/manual/en/function.array-slice.php
     */
    public function slice($offset, $length, $preserve_keys = FALSE) {
      if (is_int($offset)) {
        if (is_int($length)) {
          if (is_bool($preserve_keys)) {
            return array_slice($this->array, $offset, $length, $preserve_keys);
          } else {
            throw new IllegalArgumentException("\$preserve_keys parameter must be a boolean.");
          }
        } else {
          throw new IllegalArgumentException("\$length parameter must be an integer.");
        }
      } else {
        throw new IllegalArgumentException("\$offset parameter must be an integer.");
      }
    }

    /**
     * Remove a portion of the array and replace it with something else.<br />
     * <b>DO NOT USE THIS METHOD AS IT IS NOT YET STABLE<b>.<br /><br />
     *
     * @param integer $offset If offset is positive then the start of removed
     * portion is at that offset from the beginning of the main array. If offset
     * is negative then it starts that far from the end of the main array.
     *
     * @param integer $length If length is omitted, removes everything from
     * offset to the end of the array. If length is specified and is positive,
     * then that many elements will be removed. If length is specified and is
     * negative then the end of the removed portion will be that many elements
     * from the end of the array. Tip: to remove everything from offset to the
     * end of the array when replacement is also specified, use GetLength() for
     * length .
     *
     * @param array $replacement If replacement array is specified, then the
     * removed elements are replaced with elements from this array. If offset
     * and length are such that nothing is removed, then the elements from the
     * replacement array are inserted in the place specified by the offset.
     * Note that keys in replacement array are not preserved. If replacement is
     * just one element it is not necessary to put array() around it, unless the
     * element is an array itself.
     *
     * @return array Returns the array consisting of the extracted elements.<br /><br />
     */
    public function splice($offset, $length, $replacement = NULL) {
      if (is_int($offset)) {
        if (is_int($offset)) {
          if (is_array($replacement)) {
            return array_splice($this->array, $offset, $length, $replacement);
          } else {
            return array_splice($this->array, $offset, $length);
          }
        } else {
          throw new IllegalArgumentException("\$length parameter must be an integer.");
        }
      } else {
        throw new IllegalArgumentException("\$offset parameter must be an integer.");
      }
    }

    /**
     * Calculate the sum of values in an array.<br />
     *
     * @return float Returns the sum of values.<br /><br />
     *
     * @link http://be.php.net/manual/en/function.array-sum.php
     */
    public function sum() {
      return floatval(array_sum($this->array));
    }

    /**
     * Removes duplicate values from an array.<br />
     * Note that keys are preserved. Unique() sorts the values treated as string
     * at first, then will keep the first key encountered for every value, and
     * ignore all following keys. It does not mean that the key of the first
     * related value from the unsorted array  will be kept.
     *
     * @return array The filtered array.<br /><br />
     *
     * @link http://be.php.net/manual/en/function.array-unique.php
     */
    public function unique() {
      $this->array = array_unique($this->array);
    }

    /**
     * Prepend one or more elements to the beginning of an array.<br />
     * Prepends passed elements to the front of the array . Note that the list
     * of elements is prepended as a whole, so that the prepended elements stay
     * in the same order. All numerical array keys will be modified to start
     * counting from zero while literal keys won't be touched.<br />
     *
     * @param mixed $value The prepended variable.
     *
     * @return integer The new number of elements in the array.<br /><br />
     *
     * @link http://be.php.net/manual/en/function.array-unshift.php
     */
    public function unshift($value) {
      array_unshift($this->array, $value);
    }

    /**
     * Sort the array.<br />
     * <b>DO NOT USE THIS METHOD AS IT IS NOT YET STABLE<b>.<br /><br />
     *
     * @param boolean $reverse Reverse the sorting order
     * @param boolean $preserve_index If set to TRUE keys are preserved.
     *
     * @return boolean TRUE on success or FALSE on failure.<br /><br />
     *
     * @link http://be.php.net/manual/en/function.arsort.php
     * @link http://be.php.net/manual/en/function.asort.php
     * @link http://be.php.net/manual/en/function.sort.php
     */
    public function sort($reverse = FALSE, $preserve_index = FALSE) {
      if (is_bool($reverse)) {
        if (is_bool($preserve_index)) {
          if ($reverse) {
            arsort($this->array);
          } else if ($preserve_index) {
            asort($this->array);
          } else {
            sort($this->array);
          }
        } else {
          throw new IllegalArgumentException("\$preserve_index parameter must be a boolean.");
        }
      } else {
        throw new IllegalArgumentException("\$reverse parameter must be a boolean.");
      }
    }

    /** Not yet implemented */
    //public function Compact() {}

    /**
     * Set the internal pointer of an array to its last element.<br />
     * Advances array 's internal pointer to the last element, and returns its
     * value.
     *
     * @return mixed The value of the last element or FALSE for empty array.<br /><br />
     *
     * @link http://be.php.net/manual/en/function.end.php
     */
    public function end() {
      end($this->array);
    }

    /** Not yet implemented. */
    //public function Extract() {}

    /**
     * Sorts an array by key, maintaining key to data correlations. This is
     * useful mainly for associative arrays.<br />
     * <b>DO NOT USE THIS METHOD AS IT IS NOT YET STABLE<b>.<br /><br />
     *
     * @param constant $flag You may modify the behavior of the sort using the
     * parameter sort_flags.
     *
     * @return boolean TRUE on success or FALSE on failure.<br /><br />
     *
     * @link http://be2.php.net/manual/en/function.ksort.php
     * @link http://be2.php.net/manual/en/function.sort.php
     */
    public function sortByKey($flag = 0) {
      return ksort($this->array, $flag);
    }

    /**
     * Sort an array using a "natural order" algorithm.<br />
     * <b>DO NOT USE THIS METHOD AS IT IS NOT YET STABLE<b>.<br /><br />
     *
     * @param boolean $sensitive Set to TRUE to sensitive order.
     *
     * @return boolean Returns TRUE on success or FALSE on failure.<br /><br />
     *
     * @link http://be2.php.net/manual/en/function.natcasesort.php
     * @link http://be2.php.net/manual/en/function.natsort.php
     */
    public function sortByNaturalOrder($sensitive = FALSE) {
      if (Validator::Validate($sensitive, Validator::BOOLEAN))
        if ($sensitive)
          return natsort($this->array);
        else
          return natcasesort($this->array);
    }

    /**
     * Advance the internal array pointer of an array.<br />
     * Behaves like GetCurrent(), with one difference. It advances the internal
     * array pointer one place forward before returning the element value.
     * That means it returns the next array value and advances the internal
     * array pointer by one.
     *
     * @return mixed The array value in the next place that's pointed to by the
     * internal array pointer, or FALSE if there are no more elements.<br /><br />
     *
     * @link http://be.php.net/manual/en/function.next.php
     */
    public function next() {
      return next($this->array);
    }

    /**
     * Rewind the internal array pointer.<br />
     *
     * @return mixed The array value in the previous place that's pointed to by
     * the internal array pointer, or FALSE if there are no more elements.<br /><br />
     *
     * @link http://be.php.net/manual/en/function.prev.php
     */
    public function previous() {
      return prev($this->array);
    }

    /**
     * Create an array containing a range of elements.<br />
     *
     * @param integer $low Low value.
     * @param integer $high High value.
     * @param integer $step If a step value is given, it will be used as the
     * increment between elements in the sequence. step should be given as a
     * positive number. If not specified, step will default to 1.
     *
     * @link http://be2.php.net/manual/en/function.range.php
     */
    public function range($low, $high, $step = 1) {
      if (is_int($low)) {
        if (is_int($high)) {
          if (is_int($step)) {
            $this->array = range($low, $high, $step);
          } else {
            throw new IllegalArgumentException("\$step parameter must be an integer.");
          }
        } else {
          throw new IllegalArgumentException("\$high parameter must be an integer.");
        }
      } else {
        throw new IllegalArgumentException("\$low parameter must be an integer.");
      }
    }

    /**
     * Set the internal pointer of an array to its first element.<br />
     * Rewinds array 's internal pointer to the first element and returns the
     * value of the first array element.
     *
     * @return mixed The value of the first array element, or FALSE if the array
     * is empty.<br /><br />
     *
     * @link http://be.php.net/manual/en/function.reset.php
     */
    public function reset() {
      return reset($this->array);
    }

    /**
     * Shuffle an array.<br />
     * Randomizes the order of the elements in the array.<br />
     *
     * @return boolean TRUE on success or FALSE on failure.<br /><br />
     *
     * @link http://be.php.net/manual/en/function.shuffle.php
     */
    public function shuffle() {
      shuffle($this->array);
    }

    /**
     * Sort an array by keys using a user-defined comparison function.<br />
     * <b>DO NOT USE THIS METHOD AS IT IS NOT YET STABLE<b>.<br /><br />
     *
     * @param string $callback
     *
     * @return boolean TRUE on success or FALSE on failure.<br /><br />
     *
     * @link http://be2.php.net/manual/en/function.uksort.php
     * @link http://be2.php.net/manual/en/function.krsort.php
     * @link http://be2.php.net/manual/en/function.sort.php
     */
    public function sortByKeyWithCallback($callback, $reverse = FALSE, $flag = SORT_REGULAR) {
      if (Validator::Validate($callback, Validator::STRING) &&
              Validator::Validate($reverse, Validator::BOOLEAN))
        if ($reverse)
          return krsort($this->array, $callback, $flag);
        else
          return uksort($this->array, $callback);
    }

    /**
     * Sort an array by values using a user-defined comparison function.<br />
     * <b>DO NOT USE THIS METHOD AS IT IS NOT YET STABLE<b>.<br /><br />
     *
     * @param string $callback The comparison function must return an integer
     * less than, equal to, or greater than zero if the first argument is
     * considered to be respectively less than, equal to, or greater than
     * the second.
     *
     * @param boolean $keep_index Determine if the index must be preserved.
     *
     * @return boolean TRUE on success or FALSE on failure.<br /><br />
     *
     * @link http://be2.php.net/manual/en/function.usort.php
     * @link http://be2.php.net/manual/en/function.uasort.php
     */
    public function sortWithCallback($callback, $keep_index = FALSE) {
      if (Validator::Validate($callback, Validator::STRING) &&
              Validator::Validate($keep_index, Validator::BOOLEAN))
        if ($keep_index)
          return uasort($this->array, $callback);
        else
          return usort($this->array, $callback);
    }

  }

?>